package com.ay.weixin.fdc.front.yongjin.event;

import java.io.IOException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletException;

import org.lizar.config.Config;
import org.lizar.config.keys.Keys;
import org.lizar.controller.Event;
import org.lizar.controller.intercepter.Before;
import org.lizar.controller.loader.BasicLoader;
import org.lizar.controller.loader.EventLoader;
import org.lizar.ioc.Container;
import org.lizar.json.JList;
import org.lizar.json.JObject;
import org.lizar.util.StringHelper;

import com.ay.weixin.config.ProjectConfig;
import com.ay.weixin.fdc.admin.category.domain.CategoryLoader;
import com.ay.weixin.fdc.boss.bank.db.BankAccountDao;
import com.ay.weixin.fdc.boss.bank.domain.BankAccount;
import com.ay.weixin.fdc.boss.user.db.UserDao;
import com.ay.weixin.fdc.boss.user.domain.FDCAgent;
import com.ay.weixin.fdc.boss.user.domain.UserBasic;
import com.ay.weixin.fdc.boss.yongjin.db.IbatisCashFlow;
import com.ay.weixin.fdc.boss.yongjin.db.IbatisCashWithdrawFlowDao;
import com.ay.weixin.fdc.boss.yongjin.domain.CashFlow;
import com.ay.weixin.fdc.boss.yongjin.domain.CashWithdrawFlow;
import com.ay.weixin.fdc.boss.yongjin.event.YongJinMC;
import com.ay.weixin.mail.domain.Email;
import com.ay.weixin.mail.domain.YongJinEmailNotify;

public class YongJinEvt extends Event implements Before{
	
	private static IbatisCashWithdrawFlowDao draw_flow_dao;
	private UserDao user_dao;
	private CategoryLoader cl;
	private BankAccountDao bank_dao;
	private static IbatisCashFlow cash_dao;
	private YongJinEmailNotify yongjinEmailNotify;
	
	@Override
	public void before(BasicLoader bl) throws ServletException, IOException {
		
	}
	
	@Override
	public void init_property() throws Exception {
		cash_dao=Container.get(IbatisCashFlow.class);
		draw_flow_dao=Container.get(IbatisCashWithdrawFlowDao.class);
		user_dao=Container.get(UserDao.class);
		bank_dao=Container.get(BankAccountDao.class);
		cl=Container.get(CategoryLoader.class);
		yongjinEmailNotify=Container.get(YongJinEmailNotify.class);
		
	}

	@Override
	public String default_handling_path() {
		return "/yongjin/*";
	}

	@Override
	public void handle(EventLoader el) throws ServletException, IOException {
		long wxproject_id=el.queryPathInt(1);
		
		if(!el.getBool("is_weixin")&&ProjectConfig._bool(wxproject_id,"weixin_only")){
			el.text("invalid visit");
			return;
		}
		if(el.getSessionAttr("user")==null){
			el.response_to_root("/fdc/login/"+wxproject_id);
			return;
		}
		if(el.queryPathCheck(2,"")){//查看佣金详细出入流
			view(el,wxproject_id);
		}else if(el.queryPathCheck(2,"withdraw")){//提现申请
			withdraw(el,wxproject_id);
		}else if(el.queryPathCheck(2,"withdraw_status")){//查看申请状态
			withdraw_status(el,wxproject_id);
		}else if(el.queryPathCheck(2,"withdraw_able")){//查看可结佣金
			withdraw_able(el,wxproject_id);
		}else if(el.queryPathCheck(2,"withdrawed")){//查看可结佣金
			withdrawed(el,wxproject_id);
		}else if(el.queryPathCheck(2,"next")){//查看佣金详细出入流，下一页
			next(el);
		}else if(el.queryPathCheck(2,"view_others")){//查看我的经纪人佣金详细出入流
			view_others(el,wxproject_id);
		}else if(el.queryPathCheck(2,"view_others_next")){
			view_others_next(el);
		}
	}
	
	private void view_others_next(EventLoader el) throws IOException, ServletException{
		long user_id=el.getLong("user_id",-1);
		long from_id=el.getLong("from_id",-1);
		JObject obj=new JObject();
		if(from_id==-1){
			obj.put("err", "lack of args");
			obj.put("data",new JList());
			el.json(obj.toString());
			return;
		}
		if(user_id==-1){
			obj.put("err", "lack of args");
			obj.put("data",new JList());
			el.json(obj.toString());
			return;
		}
		UserBasic user=null;
		try {
			user=user_dao.getById(user_id);
		} catch (SQLException e1) {
			e1.printStackTrace();
			obj.put("err", el.i18("fdc_cash_withdraw_server_error"));
			obj.put("data",new JList());
			el.json(obj.toString());
			return;
		}
		if(user==null){
			obj.put("err", "user not exists");
			obj.put("data",new JList());
			el.json(obj.toString());
			return;
		}
		
		UserBasic me=el.getSessionAttr("user",UserBasic.class);
		
		if(!StringHelper.equals(me.getInvite_code(), user.getFrom_invite_code())){
			obj.put("err", "user not matched");
			obj.put("data",new JList());
			el.json(obj.toString());
			return;
		}
		
		
		List<CashFlow> list=null;
		
		try {
			list=cash_dao.getTotalFlowNextPage(user.getId(), from_id);
		} catch (SQLException e) {
			e.printStackTrace();
			obj.put("err", "server error");
			obj.put("data",new JList());
			el.json(obj.toString());
			return;
		}
		
		JList jlist=JList.toJson(list);
		obj.put("data",jlist);
		el.json(obj.toString());
	}
	
	public void view_others(EventLoader el,long wxproject_id) throws IOException, ServletException{
		long user_id=el.getLong("user_id",-1);
		if(user_id==-1){
			view(el,wxproject_id);
			return;
		}
		UserBasic user=null;
		try {
			user=user_dao.getById(user_id);
		} catch (SQLException e1) {
			e1.printStackTrace();
			el.setAttr("msg",el.i18("fdc_cash_withdraw_server_error"));
			view(el,wxproject_id);
			return;
		}
		if(user==null){
			System.out.println(1);
			view(el,wxproject_id);
			return;
		}
		
		UserBasic me=el.getSessionAttr("user",UserBasic.class);
		if(!StringHelper.equals(me.getInvite_code(), user.getFrom_invite_code())){
			System.out.println(2);
			view(el,wxproject_id);
			return;
		}
		
		List<CashFlow> list=null;
		float total=0;
		try {
			total=cash_dao.countCashAll(user_id, CashFlow.FLOW_IN);
			list=cash_dao.getTotalFlowFisrtPage(user_id);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",el.i18("fdc_cash_withdraw_server_error"));
			view(el,wxproject_id);
			return;
		}
		el.setAttr("user",user);
		el.setAttr("list",list);
		el.setAttr("total",total);
		el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/view_others.vm");
	}
	
	private void withdraw_able(EventLoader el,long wxproject_id) throws IOException, ServletException{
		FDCAgent user=el.getSessionAttr("user",FDCAgent.class);
		List<CashFlow> list=null;
		float closed_commission=0;
		float total=0;
		try {
			list=cash_dao.getSpecificFlow(user.getId(),CashFlow.FLOW_IN,CashFlow.IN_STATUS_IN);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		try {
			total=cash_dao.countSpecificInStatusFlow(user.getId(),CashFlow.IN_STATUS_IN);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",  el.i18("bank.db.failure"));
		}
		
		try {
			closed_commission=cash_dao.countCashAll(user.getId(),CashFlow.FLOW_OUT);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",  el.i18("bank.db.failure"));
		}
		
		el.setAttr("list",list);
		el.setAttr("total",total);
		el.setAttr("closed_commission",closed_commission);
		el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_able.vm");
	}
	
	private void withdrawed(EventLoader el,long wxproject_id) throws IOException, ServletException{
		FDCAgent user=el.getSessionAttr("user",FDCAgent.class);
		List<CashFlow> list=null;
		float closed_commission=0;
		float total=0;
		try {
			list=cash_dao.getCurrentFlowIn(user.getId(),CashFlow.FLOW_OUT);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		try {
			total=cash_dao.countSpecificInStatusFlow(user.getId(),CashFlow.IN_STATUS_IN);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",  el.i18("bank.db.failure"));
		}
		
		try {
			closed_commission=cash_dao.countCashAll(user.getId(),CashFlow.FLOW_OUT);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",  el.i18("bank.db.failure"));
		}
		
		el.setAttr("list",list);
		el.setAttr("total",total);
		el.setAttr("closed_commission",closed_commission);
		el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdrawed.vm");
	}
	
	private void next(EventLoader el) throws IOException, ServletException{
		UserBasic user=el.getSessionAttr("user", UserBasic.class);
		long from_id=el.getLong("from_id",-1);
		JObject obj=new JObject();
		if(from_id==-1){
			obj.put("err", "lack of args");
			obj.put("data",new JList());
			el.json(obj.toString());
			return;
		}
		List<CashFlow> list=null;
		
		try {
			list=cash_dao.getTotalFlowNextPage(user.getId(), from_id);
		} catch (SQLException e) {
			e.printStackTrace();
			obj.put("err", "server error");
			obj.put("data",new JList());
			el.json(obj.toString());
			return;
		}
		
		JList jlist=JList.toJson(list);
		obj.put("data",jlist);
		el.json(obj.toString());
	}
	
	
	
	private void withdraw_status(EventLoader el,long wxproject_id) throws IOException, ServletException{
		long cash_id=el.getLong("id");
		CashFlow withdraw=null;
		try {
			withdraw=cash_dao.get(cash_id);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",el.i18("fdc_cash_withdraw_server_error"));
			view(el,wxproject_id);
			return;
		}
		if(withdraw==null){
			el.setAttr("msg",el.i18("fdc_cash_withdraw_not_exists"));
			view(el,wxproject_id);
			return;
		}
		List<CashWithdrawFlow> flist=null;
		
		try {
			flist=draw_flow_dao.getByDrawId(cash_id);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",el.i18("fdc_cash_withdraw_server_error"));
			view(el,wxproject_id);
			return;
		}
		
		el.setAttr("withdraw", withdraw);
		el.setAttr("flist", flist);
		el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_status.vm");
	}
	
	private void withdraw(EventLoader el,long wxproject_id) throws IOException, ServletException{
		FDCAgent user=el.getSessionAttr("user",FDCAgent.class);
		
		if(user.getProfile_verify()!=UserBasic.PROFILE.VERIFIED.getValue()){
			el.setAttr("msg",String.format(el.i18("fdc_cash_withdraw_not_verified")));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		List<BankAccount> bak=null;
		try {
			bak=bank_dao.getByUserId(user.getId());
		} catch (SQLException e1) {
			e1.printStackTrace();
			el.setAttr("msg",String.format(el.i18("fdc_cash_withdraw_server_error")));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		if(bak==null||bak.isEmpty()){
			el.setAttr("msg",String.format(el.i18("fdc_cash_withdraw_no_bank_binding")));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		
		List<CashFlow> list=null;
		try {
			list=cash_dao.getSpecificFlow(user.getId(),CashFlow.FLOW_IN,CashFlow.IN_STATUS_IN);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",String.format(el.i18("fdc_cash_withdraw_server_error")));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		float total=0;
		
		try {
			total=cash_dao.countSpecificInStatusFlow(user.getId(),CashFlow.IN_STATUS_IN);
		} catch (SQLException e1) {
			e1.printStackTrace();
			el.setAttr("msg",String.format(el.i18("fdc_cash_withdraw_server_error")));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		
		float withdraw_more_than=ProjectConfig.getFloat(wxproject_id,"fdc_cash_flow.withdraw_more_than");
		int withdraw_days_limit=ProjectConfig.getInt(wxproject_id,"fdc_cash_flow.withdraw_days_limit");
		if(total==0){
			el.setAttr("msg",el.i18("fdc_cash_withdraw_no_cash"));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		if(total<withdraw_more_than){
			el.setAttr("msg",String.format(el.i18("fdc_cash_withdraw_number_less_than"),Float.toString(withdraw_more_than)));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		CashFlow withdraw=null;
		try{
			withdraw=cash_dao.getLastWithdraw(user.getId());
		}catch(Exception e){
			e.printStackTrace();
			el.setAttr("msg",String.format(el.i18("fdc_cash_withdraw_server_error")));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		
		if(withdraw!=null){
			long one_day=3600*24*1000;
			long timestamp=withdraw.getTimestamp();
			if(timestamp>0){
				if(timestamp>(System.currentTimeMillis()-withdraw_days_limit*one_day)){
					el.setAttr("msg",String.format(el.i18("fdc_cash_withdraw_frequence_meet"),withdraw_days_limit));
					el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
					return;
				}else if(timestamp<=(System.currentTimeMillis()-withdraw_days_limit*one_day)&&withdraw.getOut_status()!=CashFlow.OUT_STATUS_CONFIRMED){
					el.setAttr("msg",el.i18("fdc_cash_withdraw_last_not_end"));
					el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
					return;
				}
			}
		}
		
		long start_id=list.get(0).getId();
		long end_id=list.get(list.size()-1).getId();
		
		try {
			cash_dao.markWithdraw(user.getId(),start_id,end_id);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",el.i18("fdc_cash_withdraw_server_error"));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		
		CashFlow newwith=new CashFlow();
		newwith.setCash(total);
		newwith.setFlow_in(CashFlow.FLOW_OUT);
		newwith.setFrom_user_id(0);
		newwith.setOut_status(CashFlow.OUT_STATUS_APPLY);
		newwith.setReason(ProjectConfig.getStr(wxproject_id,"fdc_cash_flow.withdraw"));
		newwith.setTimestamp(System.currentTimeMillis());
		newwith.setUser_id(user.getId());
		newwith.setUpdate_timestamp(System.currentTimeMillis());
		try {
			cash_dao.insert(newwith);
			newwith=cash_dao.getLastWithdraw(user.getId());
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",el.i18("fdc_cash_withdraw_server_error"));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		
		CashWithdrawFlow draw_flow=new CashWithdrawFlow();
		draw_flow.setDraw_id(newwith.getId());
		draw_flow.setOper(-1);
		draw_flow.setOper_timestamp(0);
		draw_flow.setStatus(CashFlow.OUT_STATUS_APPLY);
		
		try {
			draw_flow_dao.insert(draw_flow);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",el.i18("fdc_cash_withdraw_server_error"));
			el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
			return;
		}
		
		YongJinMC.withdraw(wxproject_id,"提现申请提交成功", user.getId(), Calendar.getInstance().getTime().toLocaleString(), "申请中", total, String.format(el.i18("fdc_cash_withdraw_sucess"),Float.toString(total)));
		sendEmail(wxproject_id,user,total,el);
		el.setAttr("msg",String.format(el.i18("fdc_cash_withdraw_sucess"),Float.toString(total)));
		el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/withdraw_result.vm");
	}
	
	public void sendEmail(long wxproject_id,FDCAgent user,float amount,EventLoader el){
		if(ProjectConfig.getBool(wxproject_id,"fdc_cash_flow.submit_notify_enable")&&Email.isEmail(ProjectConfig.getStr(wxproject_id,"fdc_cash_flow.submit_notify_email"))){
			try{
				yongjinEmailNotify.sendYongjinSubmitNotify( wxproject_id,user.getName(),user.getPhone(), new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()), 
					amount, ProjectConfig.getStr(wxproject_id,"fdc_cash_flow.submit_notify_email"), Config.xpathgetStr("server_info.root")+"/menu", el);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}

	private void view(EventLoader el,long wxproject_id) throws IOException, ServletException{
		FDCAgent user=el.getSessionAttr("user",FDCAgent.class);
		List<CashFlow> list=null;
		float closed_commission=0;
		float total=0;
		try {
			list=cash_dao.getTotalFlowFisrtPage(user.getId());
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		try {
			total=cash_dao.countSpecificInStatusFlow(user.getId(),CashFlow.IN_STATUS_IN);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",  el.i18("bank.db.failure"));
		}
		
		try {
			closed_commission=cash_dao.countCashAll(user.getId(),CashFlow.FLOW_OUT);
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",  el.i18("bank.db.failure"));
		}
		
		List<BankAccount> bank_list=null;
		
		try {
			bank_list=bank_dao.getByUserId(user.getId());
		} catch (SQLException e) {
			e.printStackTrace();
			el.setAttr("msg",  el.i18("bank.db.failure"));
		}
		
		el.setAttr("bank_list",bank_list);
		el.setAttr("bank_category",cl.get("bank"));
		
		el.setAttr("list",list);
		
		el.setAttr("total",total);
		el.setAttr("closed_commission",closed_commission);
		el.template("/WEB-INF/template/app/"+wxproject_id+"/yongjin/index.vm");
	}
	
	private float sumCash(List<CashFlow> flist){
		float total=0.00f;
		if(flist==null)return 0;
		for(CashFlow f:flist){
			total+=f.getCash();
		}
		return total;
	}
	
}
